﻿using System;
using System.Collections.Generic;
using System.Text;
using RayD.Repository.Entites.SystemModule;
using RayD.Core;
using RayD.Repository;
using Dapper;
using System.Data;
using System.Linq;
using RayD.Repository.Core;

namespace RayD.App.SystemModule
{
    public class DepartmentApp
    {

        #region 构造函数注入
        private IRepository BaseRepository;
        private ManaframeApp _manaframe;
        public DepartmentApp(IRepository repository, ManaframeApp manaframe)
        {
            this.BaseRepository = repository;
            this._manaframe = manaframe;
        }
        #endregion

        #region 获取数据
        /// <summary>
        /// 获取列表数据
        /// </summary>
        /// <param name="queryJson">查询条件</param>
        /// <returns></returns>
        public IEnumerable<DepartmentEntity> GetList(string queryJson)
        {
            var expression = LinqExtensions.True<DepartmentEntity>();

            var queryParam = queryJson.ToJObject();
            if (!queryParam["B_ManaframeId"].IsEmpty())
            {
                expression = expression.And(c => c.B_ManaframeId == queryParam["B_ManaframeId"].ToString());
            }
            if (!queryParam["B_FullName"].IsEmpty())
            {
                expression = expression.And(c => c.B_FullName.Contains(queryParam["B_FullName"].ToString()));
            }
            if (!queryParam["B_EnCode"].IsEmpty())
            {
                expression = expression.And(c => c.B_EnCode.Contains(queryParam["B_EnCode"].ToString()));
            }
            if (!queryParam["B_CreateDate"].IsEmpty())
            {
                expression = expression.And(c => c.B_CreateDate >= queryParam["B_CreateDate"][0].ToDate() && c.B_CreateDate <= queryParam["B_CreateDate"][1].ToDate());
            }
            /*关联架构*/
            var userInfo = AuthenticationHelper.LoginUserInfo;
            if (!userInfo.isSystem)
            {
                var manaframeIds = _manaframe.GetSubNodes(userInfo.manaframeId);
                expression = expression.And(c => manaframeIds.IndexOf(c.B_ManaframeId) >= 0);
            }
            return BaseRepository
                .IQueryable(expression)
                .OrderBy(c => c.B_SortCode);
        }
        /// <summary>
        /// 获取分页列表数据
        /// </summary>
        /// <param name="queryJson">查询条件</param>
        /// <param name="pagination">分页参数</param>
        /// <returns></returns>
        public IEnumerable<DepartmentEntity> GetPageList(string queryJson, Pagination pagination)
        {
            var expression = LinqExtensions.True<DepartmentEntity>();
            var queryParam = queryJson.ToJObject();
            if (!queryParam["B_ManaframeId"].IsEmpty())
            {
                expression = expression.And(c => c.B_ManaframeId == queryParam["B_ManaframeId"].ToString());
            }
            if (!queryParam["B_FullName"].IsEmpty())
            {
                expression = expression.And(c => c.B_FullName.Contains(queryParam["B_FullName"].ToString()));
            }
            if (!queryParam["B_EnCode"].IsEmpty())
            {
                expression = expression.And(c => c.B_EnCode.Contains(queryParam["B_EnCode"].ToString()));
            }
            if (!queryParam["B_CreateDate"].IsEmpty())
            {
                expression = expression.And(c => c.B_CreateDate >= queryParam["B_CreateDate"][0].ToDate() && c.B_CreateDate <= queryParam["B_CreateDate"][1].ToDate());
            }
            /*关联架构*/
            var userInfo = AuthenticationHelper.LoginUserInfo;
            if (!userInfo.isSystem)
            {
                var manaframeIds = _manaframe.GetSubNodes(userInfo.manaframeId);
                expression = expression.And(c => manaframeIds.IndexOf(c.B_ManaframeId) >= 0);
            }
            var list = this.BaseRepository.IQueryable(expression)
                            .OrderBy(pagination.sidx, pagination.sord)
                            .ToTree();
            /***********************分页处理*********************/
            var rowsData = list.Skip(pagination.pageSize * (pagination.currentPage - 1)).Take(pagination.pageSize);
            pagination.records = list.Count();

            return rowsData;
        }
        /// <summary>
        /// 获取部门本身和子组织的id
        /// </summary>
        /// <param name="B_ManaframeId">组织ID</param>
        /// <param name="B_ParentId">父级ID</param>
        /// <returns></returns>
        [Caching]
        public virtual List<string> GetSubNodes(string B_ManaframeId, string B_ParentId)
        {
            if (B_ParentId.IsEmpty())
            {
                return new List<string>();
            }
            List<string> res = new List<string>();
            res.Add(B_ParentId);

            var expression = LinqExtensions.True<DepartmentEntity>().And(c => c.B_EnabledMark == EnabledMark.Enabled);
            if (!B_ManaframeId.IsEmpty())
            {
                expression = expression.And(c => c.B_ManaframeId == B_ManaframeId);
            }
            var list = BaseRepository.IQueryable(expression);
            list.ToTree(B_ParentId).GetSubNodes(res);
            return res;
        }
        /// <summary>
        /// 获取树型列表数据
        /// </summary>
        /// <param name="account">登录账户(缓存键)</param>
        /// <param name="B_ManaframeId">组织架构主键</param>
        /// <param name="isDeep">是否深度获取</param>
        /// <returns></returns>
        [Caching]
        public virtual List<DepartmentEntity> GetTreeList(string account, string B_ManaframeId, bool isDeep)
        {
            var list = this.GetListByManaId(account, B_ManaframeId, isDeep);
            return list.ToTree().ToList();
        }
        /// <summary>
        /// 根据架构主键获取列表数据
        /// </summary>
        /// <param name="account">登录账户(缓存键)</param>
        /// <param name="B_ManaframeId">架构主键</param>
        /// <param name="isDeep">是否深度获取</param>
        /// <returns></returns>
        [Caching]
        public virtual List<DepartmentEntity> GetListByManaId(string account, string B_ManaframeId, bool isDeep)
        {
            StringBuilder strSql = new StringBuilder(200);
            strSql.Append(@"Select 
                                t.B_DepartmentId
                                ,t.B_ManaframeId
                                ,t.B_ParentId
                                ,t.B_EnCode
                                ,t2.B_FullName ManaframeName
                                ,t.B_FullName
                                ,t.B_Nature
                                ,t.B_Manager
                                ,t.B_OuterPhone
                                ,t.B_InnerPhone
                                ,t.B_Email
                                ,t.B_Fax
                                ,t.B_SortCode
                                ,t.B_EnabledMark
                                ,t.B_Description
                                ,t.B_CreateDate
                                ,t.B_CreateUserId
                                ,t.B_CreateUserName
                                ,t.B_ModifyDate
                                ,t.B_ModifyUserId
                                ,t.B_ModifyUserName
                             From BASE_DEPARTMENT t
                            LEFT JOIN BASE_MANAFRAME t2 ON (t.B_ManaframeId = t2.B_ManaframeId)
            ");
            strSql.Append("  WHERE t.B_EnabledMark = 1 ");

            List<DepartmentEntity> resList = new List<DepartmentEntity>();

            if (isDeep)
            {
                //返回包括子组织下所有的部门
                var list = BaseRepository.FindList<DepartmentEntity>(strSql.ToString())
                    .OrderBy(c => c.B_ManaframeId)
                    .AsList();
                list.ForEach(c => c.B_FullName = $"【{c.ManaframeName}】{c.B_FullName}");

                if (!B_ManaframeId.IsEmpty())
                {
                    var manaNodes = _manaframe.GetSubNodes(B_ManaframeId);
                    for (int i = 0; i < manaNodes.Length(); i++)
                    {
                        resList.AddRange(list.FindAll(c => c.B_ManaframeId == manaNodes[i]));
                    }
                }
                else
                {
                    resList = list;
                }
            }
            else
            {
                //返回当前组织下所有的部门
                var dp = new DynamicParameters(new { });
                if (!B_ManaframeId.IsEmpty())
                {
                    dp.Add("B_ManaframeId", B_ManaframeId, DbType.String);
                    strSql.Append(" And t.B_ManaframeId = @B_ManaframeId ");
                }

                strSql.Append(" Order By t.B_SortCode ");
                resList = BaseRepository.FindList<DepartmentEntity>(strSql.ToString(), dp).ToList();
            }
            /*关联架构*/
            var userInfo = AuthenticationHelper.LoginUserInfo;
            if (!userInfo.isSystem)
            {
                var manaframeIds = _manaframe.GetSubNodes(userInfo.manaframeId);
                resList = resList.FindAll(c => manaframeIds.IndexOf(c.B_ManaframeId) >= 0);
            }
            return resList;
        }
        #endregion

        #region 提交数据
        /// <summary>
        /// 保存实体(新增,编辑)
        /// </summary>
        /// <param name="formEntity"></param>
        [RemoveCache]
        public virtual (bool, string) SaveForm(DepartmentEntity formEntity)
        {
            //字段验重
            if (ValidateExist(formEntity.B_DepartmentId, "B_FullName", formEntity.B_FullName, formEntity.B_ManaframeId)) return (false, "部门名称已存在！");
            if (ValidateExist(formEntity.B_DepartmentId, "B_EnCode", formEntity.B_EnCode, formEntity.B_ManaframeId)) return (false, "部门编号已存在！");
            if (!formEntity.B_DepartmentId.IsEmpty())
            {
                //编辑(Null、主键不会更改)
                formEntity.Modify();
                this.BaseRepository.Update(formEntity);
            }
            else
            {
                //新增
                formEntity.Create();
                this.BaseRepository.Insert(formEntity);
            }
            return (true, "保存成功！");
        }
        /// <summary>
        /// 删除实体
        /// </summary>
        /// <param name="formEntity"></param>
        [RemoveCache]
        public virtual (bool, string) DeleteForm(DepartmentEntity formEntity)
        {
            this.BaseRepository.Delete(formEntity);
            return (true, "删除成功！");
        }
        /// <summary>
        /// 状态更改
        /// <summary>
        /// <param name="formEntity">数据实体</param>
        /// <returns></returns>
        [RemoveCache]
        public virtual (bool, string) ChangeState(DepartmentEntity formEntity)
        {
            if (!formEntity.B_DepartmentId.IsEmpty())
            {
                this.BaseRepository.Update(new DepartmentEntity() { B_DepartmentId = formEntity.B_DepartmentId, B_EnabledMark = formEntity.B_EnabledMark });
                return (true, "更改成功！");
            }
            else
            {
                return (false, "更改失败！");
            }
        }
        #endregion

        #region 扩展方法

        #endregion

        #region 数据验证
        /// <summary>
        /// 验证字段值是否存在
        /// </summary>
        /// <param name="id">实体主键</param>
        /// <param name="field">字段名</param>
        /// <param name="value">字段值</param>
        /// <param name="manaId">架构主键</param>
        /// <returns></returns>
        public bool ValidateExist(string id, string field, string value, string manaId)
        {
            var expression = LinqExtensions.True<DepartmentEntity>();
            if (!string.IsNullOrEmpty(id))
            {
                expression = expression.And(t => t.B_DepartmentId != id);
            }
            if (!string.IsNullOrEmpty(manaId))
            {
                expression = expression.And(t => t.B_ManaframeId == manaId);
            }
            return this.BaseRepository.IQueryable(expression).Exist(field, value);
        }
        #endregion
    }
}
